﻿Imports System.Text.RegularExpressions
Imports System.Drawing
Imports System.Xml
Imports System.Drawing.Image
Imports System.Drawing.Drawing2D
Imports System.Drawing.Imaging

''' <summary>
''' 文件上传类
''' </summary>
''' <remarks></remarks>
Public Class Uploader
    Inherits ClsBase
    Private Shadows mErrMessage As String
    Private mAllowTypes As String
    Private mImgTypes As String
    Private mUploadBasePath As String
    Private mUploadPath As String
    Private mThumbnailPath As String
    Private mWatermarkpic As String
    Private mWatermarktext As String
    Private mWatermarkfontname As String
    Private mWatermarkfontsize As Integer = -1
    Private mWatermarktype As Integer = -1
    Private mMaxUploadSize As Integer = -1
    Private mUploadFilesXmlDocument As Xml.XmlDocument
    Private mUploadFilesCreateTime As String
    Private mWatermarkalpha As Single
    Private mXmlUrl As String

    ''' <summary>
    ''' 错误信息
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Shadows ReadOnly Property ErrMessage() As String
        Get
            Return mErrMessage
        End Get
    End Property

    ''' <summary>
    ''' 允许上传的类型
    ''' </summary>
    ''' <value>字符串|分隔</value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' 
    Public ReadOnly Property AllowTypes() As String
        Get
            If mAllowTypes Is Nothing Then
                mAllowTypes = Config.AppConfig.ConfigInfo.AllowUploadTypes
            End If
            Return mAllowTypes
        End Get
    End Property

    ''' <summary>
    ''' 图片类型
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ImgTypes() As String
        Get
            If mImgTypes Is Nothing Then
                mImgTypes = Config.AppConfig.ConfigInfo.ImgTypes
            End If
            Return mImgTypes
        End Get
    End Property

    ''' <summary>
    ''' 最大上传大小(单位K)
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property MaxUploadSize() As Integer
        Get
            If mMaxUploadSize = -1 Then
                mMaxUploadSize = Config.AppConfig.ConfigInfo.MaxUploadSize
            End If
            Return mMaxUploadSize
        End Get
    End Property

    ''' <summary>
    ''' 文件上传的基础路径
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property UploadBasePath() As String
        Get
            If mUploadBasePath Is Nothing Then
                mUploadBasePath = Config.AppConfig.ConfigInfo.UploadBasePath
            End If
            Return mUploadBasePath
        End Get
    End Property

    ''' <summary>
    ''' 上传目录
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property UploadPath() As String
        Get
            If mUploadPath Is Nothing Then
                mUploadPath = Config.AppConfig.ConfigInfo.UploadPath
            End If
            Return mUploadPath
        End Get
    End Property

    ''' <summary>
    ''' 上传缩略图目录
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property ThumbnailPath() As String
        Get
            If mThumbnailPath Is Nothing Then
                mThumbnailPath = Config.AppConfig.ConfigInfo.ThumbnailPath
            End If
            Return mThumbnailPath
        End Get
    End Property

    ''' <summary>
    ''' 水印类型
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Watermarktype() As Integer
        Get
            If mWatermarktype = -1 Then
                mWatermarktype = Config.AppConfig.ConfigInfo.Watermarktype
            End If
            Return mWatermarktype
        End Get
    End Property

    ''' <summary>
    ''' 透明度
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property colorMatrixElements() As Single
        Get
            If mWatermarkalpha <= 0 Then
                mWatermarkalpha = Config.AppConfig.ConfigInfo.Watermarkalpha
                If mWatermarkalpha <= 0 Then mWatermarkalpha = 0.2F
            End If
            Return mWatermarkalpha
        End Get

        Set(value As Single)
            mWatermarkalpha = value
        End Set
    End Property

    ''' <summary>
    ''' 水印图片
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Watermarkpic() As String
        Get
            If mWatermarkpic Is Nothing Then
                mWatermarkpic = Config.AppConfig.ConfigInfo.Watermarkpic
                If String.IsNullOrEmpty(mWatermarkpic) Then
                    mWatermarkpic = "/watermark.jpg"
                End If
                mWatermarkpic = System.Web.HttpContext.Current.Server.MapPath(mWatermarkpic)
            End If
            Return mWatermarkpic
        End Get

        Set(value As String)
            mWatermarkpic = value
        End Set
    End Property

    ''' <summary>
    ''' 水印文字
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Watermarktext() As String
        Get
            If mWatermarktext Is Nothing Then
                mWatermarktext = String.Format(Config.AppConfig.ConfigInfo.Watermarktext, Now)
            End If
            Return mWatermarktext
        End Get
    End Property

    ''' <summary>
    ''' 水印文字字体
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Watermarkfontname() As String
        Get
            If mWatermarkfontname Is Nothing Then
                mWatermarkfontname = Config.AppConfig.ConfigInfo.Watermarkfontname
                If String.IsNullOrEmpty(mWatermarkfontname) Then mWatermarkfontname = "宋体"
            End If
            Return mWatermarkfontname
        End Get
    End Property

    ''' <summary>
    ''' 水印文字字体大小
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Watermarkfontsize() As Integer
        Get
            If mWatermarkfontsize = -1 Then
                mWatermarkfontsize = Config.AppConfig.ConfigInfo.Watermarkfontsize
                If mWatermarkfontsize <= 0 Then mWatermarkfontsize = 12
            End If
            Return mWatermarkfontsize
        End Get
    End Property

    ''' <summary>
    ''' 保存上传的文件
    ''' </summary>
    ''' <param name="fnPostedFile">文件流</param>
    ''' <param name="uploadCtrl">上传配置</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' 
    Public Function SavePostedFile(ByVal fnPostedFile As Web.HttpPostedFile, ByVal uploadCtrl As Config.UploadControl) As String

        If fnPostedFile Is Nothing OrElse fnPostedFile.ContentLength = 0 Then
            mErrMessage = "上传的文件对象或内容为空!!"
            Return String.Empty
        End If

        Dim OrgFileName As String = fnPostedFile.FileName
        Dim FilePath As String
        Dim ThumbnailFile As String
        Dim RandomPath As String = Util.GetRandomDirectory()
        Dim RandomFile As String = Util.GetRandomFileName(OrgFileName)
        Dim VFileUrl As String = String.Concat(RandomPath, RandomFile)

        Dim rThumbnailPath As String, rUploadPath As String

        '是否传送缩略目录
        If String.IsNullOrEmpty(uploadCtrl.ThumbnailPath) Then
            rThumbnailPath = ThumbnailPath
        Else
            rThumbnailPath = uploadCtrl.ThumbnailPath
        End If

        '是否传送上传目录
        If String.IsNullOrEmpty(uploadCtrl.UploadPath) Then
            rUploadPath = UploadPath
        Else
            rUploadPath = uploadCtrl.UploadPath
        End If

        '是否存在基础目录
        If Not String.IsNullOrEmpty(UploadBasePath) AndAlso IO.Directory.Exists(UploadBasePath) Then
            FilePath = String.Concat(UploadBasePath, rUploadPath, VFileUrl)
            ThumbnailFile = String.Concat(UploadBasePath, rThumbnailPath, VFileUrl)
        Else
            FilePath = System.Web.HttpContext.Current.Server.MapPath(String.Concat(rUploadPath, VFileUrl))
            ThumbnailFile = System.Web.HttpContext.Current.Server.MapPath(String.Concat(rThumbnailPath, VFileUrl))
        End If

        '检查是否允许上传的类型
        If Not Regex.IsMatch(OrgFileName, String.Format(".({0})$", uploadCtrl.AllowUploadTypes), RegexOptions.IgnoreCase) Then
            mErrMessage = String.Format("只允许上传({0})格式的文件.", uploadCtrl.AllowUploadTypes.Replace("|", "，"))
            Return String.Empty
        End If

        '检查上传是否符合大小
        If fnPostedFile.ContentLength > (uploadCtrl.MaxUploadSize * 1024) Then
            mErrMessage = String.Format("您上传文件超过({0}K)限制.", uploadCtrl.MaxUploadSize)
            Return String.Empty
        End If


        '检查是否图片类型
        If Regex.IsMatch(OrgFileName, String.Format(".({0})$", ImgTypes), RegexOptions.IgnoreCase) Then
            Dim oImage As Image = Image.FromStream(fnPostedFile.InputStream)
            '检查最小图像尺寸
            If Not String.IsNullOrEmpty(uploadCtrl.MinCanvas) AndAlso uploadCtrl.MinCanvas.Split(CChar(",")).Length = 2 Then
                Dim c As String() = uploadCtrl.MinCanvas.Split(CChar(","))
                If IsNumeric(c(0)) AndAlso IsNumeric(c(1)) Then
                    Dim width As Integer = 0, height As Integer = 0

                    width = CInt(c(0))
                    height = CInt(c(1))
                    If width > 0 And oImage.Width < width Then
                        mErrMessage = String.Format("您上传的图片太小，宽度不得小于{0}像素.", width)
                        Return String.Empty
                    End If

                    If height > 0 And oImage.Height < height Then
                        mErrMessage = String.Format("您上传的图片太小，高度不得小于{0}像素", height)
                        Return String.Empty
                    End If
                End If
            End If

            '检查是否需要缩略图
            If uploadCtrl.ThumbnailMode > 0 Then
                If Not IO.Directory.Exists(IO.Path.GetDirectoryName(ThumbnailFile)) Then
                    IO.Directory.CreateDirectory(IO.Path.GetDirectoryName(ThumbnailFile))
                End If

                If uploadCtrl.ThumbnailMode = 200 Then
                    CreateImage(oImage, ThumbnailFile, uploadCtrl.ThumbnailWidth, uploadCtrl.ThumbnailHeight, uploadCtrl.Quality)
                Else
                    MakeThumbnail(oImage, ThumbnailFile, uploadCtrl)
                End If

            End If

            REM 是否是图片

            If Not IO.Directory.Exists(IO.Path.GetDirectoryName(FilePath)) Then
                IO.Directory.CreateDirectory(IO.Path.GetDirectoryName(FilePath))
            End If

            If uploadCtrl.WaterMarkType = 0 And String.IsNullOrEmpty(uploadCtrl.Canvas) Then
                'fnPostedFile.SaveAs(FilePath)
                oImage.Save(FilePath)
            Else
                If Not SaveUploadImage(FilePath, oImage, uploadCtrl) Then
                    Return String.Empty
                End If
            End If
            oImage.Dispose()
            oImage = Nothing
        Else
            Try
                If Not IO.Directory.Exists(IO.Path.GetDirectoryName(FilePath)) Then
                    IO.Directory.CreateDirectory(IO.Path.GetDirectoryName(FilePath))
                End If
                fnPostedFile.SaveAs(FilePath)
            Catch ex As Exception
                mErrMessage = ex.Message
                Return String.Empty
            End Try

        End If

        Return VFileUrl

    End Function

    ''' <summary>
    ''' 保存上传图片
    ''' </summary>
    ''' <param name="LocalFilePath">保存的文件名</param>
    ''' <param name="originalImg">生成的缩略图</param>
    ''' <param name="uploadCtrl">上传配置</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SaveUploadImage(ByVal LocalFilePath As String, ByVal originalImg As Image, ByVal uploadCtrl As Config.UploadControl) As Boolean

        Try
            Dim width As Integer = 0, height As Integer = 0

            '是否指定画布大小
            If Not String.IsNullOrEmpty(uploadCtrl.Canvas) AndAlso uploadCtrl.Canvas.Split(CChar(",")).Length = 2 Then
                Dim c As String() = uploadCtrl.Canvas.Split(CChar(","))
                If IsNumeric(c(0)) AndAlso IsNumeric(c(1)) Then
                    width = CInt(c(0))
                    height = CInt(c(1))
                End If
            Else
                width = originalImg.Width
                height = originalImg.Height
            End If
            Dim position As String = uploadCtrl.Position
            '是否生成水印

            If uploadCtrl.WaterMarkType = -1 Then uploadCtrl.WaterMarkType = Watermarktype

            Select Case uploadCtrl.WaterMarkType
                Case 1
                    '文字水印
                    If String.IsNullOrEmpty(position) Then position = "RightBottom"
                    If String.IsNullOrEmpty(Watermarktext) Then
                        CreateImage(originalImg, LocalFilePath, width, height, uploadCtrl.Quality)
                    Else
                        CreateImage(originalImg, LocalFilePath, width, height, uploadCtrl.Quality, uploadCtrl.WaterMarkText, position)
                    End If
                Case 2
                    '图片水印
                    If uploadCtrl.Watermarkalpha > 0 Then colorMatrixElements = uploadCtrl.Watermarkalpha
                    If String.IsNullOrEmpty(position) Then position = "Center"
                    CreateImage(originalImg, LocalFilePath, width, height, uploadCtrl.Quality, uploadCtrl.WaterMarkType, Watermarkpic, position)
                Case Else
                    '不需要水印
                    CreateImage(originalImg, LocalFilePath, width, height, uploadCtrl.Quality)
            End Select
            Return True
        Catch ex As Exception
            mErrMessage = ex.Message
        End Try
        Return False
    End Function

    ''' <summary>
    ''' 生成缩略图
    ''' </summary>
    ''' <param name="originalImage"></param>
    ''' <param name="ThumbnailFile"></param>
    ''' <remarks></remarks>
    Public Sub MakeThumbnail(ByVal originalImage As Image, ByVal ThumbnailFile As String, ByVal uploadCtrl As Config.UploadControl)
        If uploadCtrl.ThumbnailWidth = -1 Then
            uploadCtrl.ThumbnailWidth = Config.AppConfig.ConfigInfo.ThumbnailWidth
        End If

        If uploadCtrl.ThumbnailHeight = -1 Then
            uploadCtrl.ThumbnailHeight = Config.AppConfig.ConfigInfo.ThumbnailHeight
        End If

        If uploadCtrl.ThumbnailMode = -1 Then
            uploadCtrl.ThumbnailMode = Config.AppConfig.ConfigInfo.ThumbnailMode
        End If

        If uploadCtrl.ThumbnailMode > 0 Then
            Util.MakeThumbnail(originalImage, ThumbnailFile, uploadCtrl.ThumbnailWidth, uploadCtrl.ThumbnailHeight, uploadCtrl.ThumbnailMode)
        End If
    End Sub

    Public Function CreateImage(ByVal originalBmp As Image, ByVal targetPath As String, ByVal width As Integer, ByVal height As Integer, quality As Integer) As Boolean
        Return CreateImage(originalBmp, targetPath, width, height, quality, 0, String.Empty, String.Empty)
    End Function

    Public Function CreateImage(ByVal originalBmp As Image, ByVal targetPath As String, ByVal width As Integer, ByVal height As Integer, quality As Integer, watertext As String, position As String) As Boolean
        Return CreateImage(originalBmp, targetPath, width, height, quality, 1, watertext, position)
    End Function

    ''' <summary>
    ''' 创建指定大小的图像
    ''' </summary>
    ''' <param name="originalBmp">源图像数据流</param>
    ''' <param name="targetPath">生成图像绝对路径</param>
    ''' <param name="width">生成图像的宽度</param>
    ''' <param name="height">生成图像的高度</param>
    ''' <remarks></remarks>
    Public Function CreateImage(ByVal originalBmp As Image, ByVal targetPath As String, ByVal width As Integer, ByVal height As Integer, quality As Integer, watertype As Integer, watertext As String, position As String) As Boolean
        ' 源图像在新图像中的位置  
        Dim left As Integer, top As Integer, lastbmp As New Bitmap(width, height)

        If (originalBmp.Width <= width And originalBmp.Height <= height) Then
            '原图像的宽度和高度都小于生成的图片大小
            left = CInt(Math.Round(CType((width - originalBmp.Width) / 2, Decimal)))
            top = CInt(Math.Round(CType((height - originalBmp.Height) / 2, Decimal)))
        Else
            ' 新图片的宽度和高度，如400*200的图像，想要生成160*120的图且不变形，  
            ' 那么生成的图像应该是160*80，然后再把160*80的图像画到160*120的画布上  
            Dim newWidth As Integer, newHeight As Integer
            If (width * originalBmp.Height < height * originalBmp.Width) Then

                newWidth = width
                newHeight = CInt(Math.Round(CType(originalBmp.Height * width / originalBmp.Width, Decimal)))
                ' 缩放成宽度跟预定义的宽度相同的，即left=0，计算top  
                left = 0
                top = CInt(Math.Round(CType((height - newHeight) / 2, Decimal)))

            Else

                newWidth = CInt(Math.Round(CType(originalBmp.Width * height / originalBmp.Height, Decimal)))
                newHeight = height

                ' 缩放成高度跟预定义的高度相同的，即top=0，计算left  
                left = CInt(Math.Round(CType((width - newWidth) / 2, Decimal)))
                top = 0
            End If


            Try
                ' 生成按比例缩放的图
                Dim bmpOut2 As New Bitmap(newWidth, newHeight)

                Using Graphics As Graphics = Graphics.FromImage(bmpOut2)
                    Graphics.InterpolationMode = Drawing2D.InterpolationMode.HighQualityBicubic
                    Graphics.FillRectangle(Brushes.White, 0, 0, newWidth, newHeight)
                    Graphics.DrawImage(originalBmp, 0, 0, newWidth, newHeight)
                End Using

                originalBmp = bmpOut2
            Catch ex As Exception
                mErrMessage = ex.Message
                Throw ex
            End Try

        End If

        '水印图
        Select Case watertype
            Case 1
                originalBmp = CreateWatertextBitmap(originalBmp, watertext, position)
            Case 2
                originalBmp = CreateWatermarkBitmap(originalBmp, watertext, position)
        End Select

        Try
            ' 最终生成的图像  
            Using graphics As Graphics = graphics.FromImage(lastbmp)
                ' 设置高质量插值法  
                graphics.CompositingMode = CompositingMode.SourceCopy
                graphics.SmoothingMode = SmoothingMode.HighQuality
                graphics.InterpolationMode = InterpolationMode.High
                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality

                ' 清空画布并以白色背景色填充  
                graphics.Clear(Color.White)

                ' 把源图画到新的画布上  
                graphics.DrawImage(originalBmp, left, top, originalBmp.Width, originalBmp.Height)

            End Using

        Catch ex As Exception
            mErrMessage = ex.Message
            Throw ex
        End Try


        ' 以下代码为保存图片时,设置压缩质量
        Dim encoderParams As New EncoderParameters()
        Dim qualitys As Long() = {quality}
        Dim encoderParam As New EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality)
        encoderParams.Param(0) = encoderParam
        '获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象.
        Dim arrayICI As ImageCodecInfo() = ImageCodecInfo.GetImageEncoders()
        Dim jpegICI As ImageCodecInfo = Nothing
        Dim x As Integer = 0
        While x < arrayICI.Length
            If arrayICI(x).FormatDescription.Equals("JPEG") Then
                jpegICI = arrayICI(x)
                '设置JPEG编码
                Exit While
            End If
            System.Math.Max(System.Threading.Interlocked.Increment(x), x - 1)
        End While

        If jpegICI Is Nothing Then
            lastbmp.Save(targetPath, jpegICI, encoderParams)
        Else
            lastbmp.Save(targetPath, Imaging.ImageFormat.Jpeg)
        End If

        lastbmp.Dispose()
        lastbmp = Nothing

    End Function

    ''' <summary>
    ''' 保存远程上传文件
    ''' </summary>
    ''' <param name="RemoteUrl">远程路径</param>
    ''' <param name="uploadCtrl">上传的配置对像</param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function SaveRemoteUpload(ByVal RemoteUrl As String, ByVal uploadCtrl As Config.UploadControl) As String
        Try

            If String.IsNullOrEmpty(RemoteUrl) Then
                mErrMessage = String.Format("远程文件不能为空！！")
                Return String.Empty
            End If

            Dim OrgFileName As String = IO.Path.GetFileName(RemoteUrl)

            Dim FilePath As String
            Dim ThumbnailFile As String
            Dim RandomPath As String = Util.GetRandomDirectory()
            Dim RandomFile As String = Util.GetRandomFileName(OrgFileName)
            Dim VFileUrl As String = String.Concat(RandomPath, RandomFile)

            '是否存在基础目录
            If Not String.IsNullOrEmpty(UploadBasePath) AndAlso IO.Directory.Exists(UploadBasePath) Then
                FilePath = String.Concat(UploadBasePath, UploadPath, VFileUrl)
                ThumbnailFile = String.Concat(UploadBasePath, ThumbnailPath, VFileUrl)
            Else
                FilePath = System.Web.HttpContext.Current.Server.MapPath(String.Concat(UploadPath, VFileUrl))
                ThumbnailFile = System.Web.HttpContext.Current.Server.MapPath(String.Concat(ThumbnailPath, VFileUrl))
            End If

            '检查是否允许上传的类型
            If Not Regex.IsMatch(OrgFileName, String.Format(".({0})$", AllowTypes), RegexOptions.IgnoreCase) Then
                mErrMessage = String.Format("只允许上传({0})格式的文件.", AllowTypes.Replace("|", ","))
                Return String.Empty
            End If

            Dim wc As New System.Net.WebClient
            Dim buffer As Byte() = wc.DownloadData(RemoteUrl)
            wc.Dispose()
            wc = Nothing

            Dim oStream As New System.IO.MemoryStream(buffer)

            '检查上传是否符合大小
            If oStream.Length > (MaxUploadSize * 1024) Then
                mErrMessage = String.Format("您上传文件超过({0}K)限制.", MaxUploadSize)
                VFileUrl = String.Empty
            Else

                If Regex.IsMatch(OrgFileName, String.Format(".({0})$", ImgTypes), RegexOptions.IgnoreCase) Then
                    Dim oImage As Image = Image.FromStream(oStream)
                    '检查最小图像尺寸
                    If Not String.IsNullOrEmpty(uploadCtrl.MinCanvas) AndAlso uploadCtrl.MinCanvas.Split(CChar(",")).Length = 2 Then
                        Dim c As String() = uploadCtrl.MinCanvas.Split(CChar(","))
                        If IsNumeric(c(0)) AndAlso IsNumeric(c(1)) Then
                            Dim width As Integer = 0, height As Integer = 0

                            width = CInt(c(0))
                            height = CInt(c(1))
                            If width > 0 And oImage.Width < width Then
                                mErrMessage = String.Format("您上传图片宽度要求最小{0}像素.", width)
                                Return String.Empty
                            End If

                            If height > 0 And oImage.Height < height Then
                                mErrMessage = String.Format("您上传图片高度要求最小{0}像素", height)
                                Return String.Empty
                            End If
                        End If
                    End If
                    If uploadCtrl.ThumbnailMode > 0 Then
                        MakeThumbnail(oImage, ThumbnailFile, uploadCtrl)
                    End If
                    If Not SaveUploadImage(FilePath, oImage, uploadCtrl) Then
                        VFileUrl = String.Empty
                    End If
                    oImage.Dispose()
                    oImage = Nothing
                Else
                    Try
                        IO.File.WriteAllBytes(FilePath, buffer)
                    Catch ex As Exception
                        mErrMessage = ex.Message
                        VFileUrl = String.Empty
                    End Try
                End If
            End If
            oStream.Close()
            oStream = Nothing
            buffer = Nothing

            Return VFileUrl
        Catch ex As Exception
            mErrMessage = ex.Message
            Return String.Empty
        End Try
    End Function

#Region "水印图片处理"

    ''' <summary>
    ''' 增加水印图片,指定增加水印的最小宽度
    ''' </summary>
    ''' <param name="image">文件流</param>
    ''' <param name="toPPath">保存的路径</param>
    ''' <param name="WaterMark"></param>
    ''' <remarks></remarks>
    Public Sub AddWaterPic(ByVal image As Image, ByVal toPPath As String, ByVal WaterMark As String)
        AddWaterPic(image, toPPath, WaterMark, 120)
    End Sub

    ''' <summary>
    ''' 给指定的图像增加水印图
    ''' </summary>
    ''' <param name="image"></param>
    ''' <param name="toPPath"></param>
    ''' <param name="WaterMark"></param>
    ''' <param name="minWidth"></param>
    ''' <remarks></remarks>
    Public Sub AddWaterPic(ByVal image As Image, ByVal toPPath As String, ByVal WaterMark As String, ByVal minWidth As Integer)
        Dim bmpformat As Drawing.Imaging.ImageFormat = image.RawFormat
        If image.Width <= minWidth Then
            image.Save(toPPath)
            Return
        End If

        Dim w As Integer = image.Width
        Dim h As Integer = image.Height
        Dim bmp As New Bitmap(image, w, h)
        image.Dispose()

        bmp.SetResolution(72.0F, 72.0F)


        Dim colorMap As Imaging.ColorMap = New Imaging.ColorMap()
        colorMap.OldColor = Color.FromArgb(255, 0, 255, 0)
        colorMap.NewColor = Color.FromArgb(0, 0, 0, 0)

        Dim imageAttributes As Imaging.ImageAttributes = New Imaging.ImageAttributes()
        Dim remapTable As Imaging.ColorMap() = {colorMap}
        imageAttributes.SetRemapTable(remapTable, Imaging.ColorAdjustType.Bitmap)

        Dim colorMatrixElements As Single()() = {New Single() {1.0F, 0.0F, 0.0F, 0.0F, 0.0F}, New Single() {0.0F, 1.0F, 0.0F, 0.0F, 0.0F}, New Single() {0.0F, 0.0F, 1.8F, 0.0F, 0.0F}, New Single() {0.0F, 0.0F, 0.0F, 0.3F, 0.0F}, New Single() {0.0F, 0.0F, 0.0F, 0.0F, 1.0F}}
        Dim wmColorMatrix As Imaging.ColorMatrix = New Imaging.ColorMatrix(colorMatrixElements)
        imageAttributes.SetColorMatrix(wmColorMatrix, Imaging.ColorMatrixFlag.Default, Imaging.ColorAdjustType.Bitmap)


        Dim copyImage As Image = System.Drawing.Image.FromFile(WaterMark)
        If copyImage.Width < w And copyImage.Height < h Then
            Dim g As Graphics = System.Drawing.Graphics.FromImage(bmp)
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias
            g.DrawImage(copyImage, New Rectangle(bmp.Width - copyImage.Width, bmp.Height - copyImage.Height, copyImage.Width, copyImage.Height), 0, 0, copyImage.Width, copyImage.Height, System.Drawing.GraphicsUnit.Pixel, imageAttributes)
            g.Dispose()
        End If
        bmp.Save(toPPath, bmpformat)

        remapTable = Nothing
        colorMatrixElements = Nothing
        wmColorMatrix = Nothing
        bmpformat = Nothing
        colorMap = Nothing
        bmp.Dispose()
        imageAttributes.Dispose()
        copyImage.Dispose()
        imageAttributes.Dispose()
    End Sub

    ''' <summary>
    ''' 给指定的图片文件增加水印文字
    ''' </summary>
    ''' <param name="fromPath"></param>
    ''' <param name="toPPath"></param>
    ''' <param name="addtext"></param>
    ''' <remarks></remarks>
    Public Sub AddWater(ByVal fromPath As String, ByVal toPPath As String, ByVal addtext As String)
        'Dim tmpStream As System.IO.Stream = System.IO.File.OpenWrite(fromPath)
        Dim image As Image = image.FromFile(fromPath)
        AddWater(image, toPPath, addtext)
        image.Dispose()
        image = Nothing
    End Sub

    ''' <summary>
    ''' 给指定的图片增加水印文字
    ''' </summary>
    ''' <param name="image">图像</param>
    ''' <param name="toPPath">生成的路径</param>
    ''' <param name="addtext">水印文字</param>
    ''' <remarks></remarks>
    Public Sub AddWater(ByVal image As Image, ByVal toPPath As String, ByVal addtext As String)
        Dim bmpformat As Drawing.Imaging.ImageFormat = image.RawFormat
        Dim w As Integer = image.Width
        Dim h As Integer = image.Height
        Dim bmp As New Bitmap(image, w, h)
        bmp.SetResolution(72.0F, 72.0F)

        Dim g As Graphics = System.Drawing.Graphics.FromImage(bmp)
        Dim f As New Font(Watermarkfontname, Watermarkfontsize, FontStyle.Regular, GraphicsUnit.Pixel)
        Dim b As New SolidBrush(Color.Black)
        Dim fm As New StringFormat
        fm.Alignment = StringAlignment.Far
        fm.LineAlignment = StringAlignment.Far

        g.DrawString(addtext, f, b, New System.Drawing.RectangleF(0, 0, w, h), fm)

        bmp.Save(toPPath, bmpformat)

        g.Dispose()
        bmp.Dispose()
        f = Nothing
        b = Nothing
        fm = Nothing
        bmpformat = Nothing
    End Sub

    ''' <summary>
    ''' 增加水印图片
    ''' </summary>
    ''' <param name="tn"></param>
    ''' <param name="WaterMarkPicPath"></param>
    ''' <param name="WatermarkPosition"></param>
    ''' <returns></returns>
    Public Function CreateWatermarkBitmap(tn As Image, WaterMarkPicPath As String, WatermarkPosition As String) As Image
        Try
            If Not IO.File.Exists(WaterMarkPicPath) Then
                Util.toLog(String.Concat(Now(), " - CreateWatermarkBitmap: ", WaterMarkPicPath, " 不存在"))
                Return tn
            End If

            '透明
            Dim colorMap As Imaging.ColorMap = New Imaging.ColorMap()
            colorMap.OldColor = Color.FromArgb(255, 0, 255, 0)
            colorMap.NewColor = Color.FromArgb(0, 0, 0, 0)

            Dim imageAttributes As Imaging.ImageAttributes = New Imaging.ImageAttributes()
            Dim remapTable As Imaging.ColorMap() = {colorMap}
            imageAttributes.SetRemapTable(remapTable, Imaging.ColorAdjustType.Bitmap)

            Dim colorMatrixElements As Single()() = {New Single() {1.0F, 0.0F, 0.0F, 0.0F, 0.0F}, New Single() {0.0F, 1.0F, 0.0F, 0.0F, 0.0F}, New Single() {0.0F, 0.0F, 1.0F, 0.0F, 0.0F}, New Single() {0.0F, 0.0F, 0.0F, Me.colorMatrixElements, 0.0F}, New Single() {0.0F, 0.0F, 0.0F, 0.0F, 1.0F}}
            Dim wmColorMatrix As Imaging.ColorMatrix = New Imaging.ColorMatrix(colorMatrixElements)
            imageAttributes.SetColorMatrix(wmColorMatrix, Imaging.ColorMatrixFlag.Default, Imaging.ColorAdjustType.Bitmap)

            '水印
            Dim wImage As Image = Image.FromFile(WaterMarkPicPath)

            If tn.Width <= wImage.Width Or tn.Height <= wImage.Height Then
                imageAttributes.Dispose()
                imageAttributes = Nothing
                wImage.Dispose()
                wImage = Nothing
                Return tn
            End If


            Dim X As Integer = 0, Y As Integer = 0
            '水印位置
            Dim r As New Rectangle()
            Select Case WatermarkPosition
                Case "Right"
                    X = tn.Width - wImage.Width
                    Y = CInt(tn.Height / 2 - wImage.Height / 2)
                    Exit Select
                Case "RightTop"
                    X = tn.Width - wImage.Width
                    Y = 0
                    Exit Select
                Case "Top"
                    X = CInt(tn.Width / 2 - wImage.Width / 2)
                    Y = 0
                    Exit Select
                Case "LeftTop"
                    X = 0
                    Y = 0
                    Exit Select
                Case "Left"
                    X = 0
                    Y = CInt(tn.Height / 2 - wImage.Height / 2)
                    Exit Select
                Case "LeftBottom"
                    X = 0
                    Y = tn.Height - wImage.Height
                    Exit Select
                Case "Bottom"
                    X = CInt(tn.Width / 2 - wImage.Width / 2)
                    Y = tn.Height - wImage.Height
                    Exit Select
                Case "RightBottom"
                    X = tn.Width - wImage.Width
                    Y = tn.Height - wImage.Height
                    Exit Select
                Case "Center"
                    X = CInt(tn.Width / 2 - wImage.Width / 2)
                    Y = CInt(tn.Height / 2 - wImage.Height / 2)
                    Exit Select
            End Select
            r.X = X
            r.Y = Y
            r.Width = wImage.Width
            r.Height = wImage.Height

            Dim g As Graphics = Graphics.FromImage(tn)

            If Not String.IsNullOrEmpty(WatermarkPosition) Then
                g.SmoothingMode = SmoothingMode.HighQuality
                g.DrawImage(wImage, r, 0, 0, wImage.Width, wImage.Height, GraphicsUnit.Pixel, imageAttributes)
            End If

            wImage.Dispose()
            wImage = Nothing

            imageAttributes.Dispose()
            imageAttributes = Nothing

            wmColorMatrix = Nothing


            Return tn

        Catch ex As Exception
            Util.toLog(String.Concat(Now(), " - CreateWatermarkBitmap:", ex.Message))
            Return tn
        End Try
    End Function

    ''' <summary>
    ''' 增加图片文字水印
    ''' </summary>
    ''' <param name="tn">图片</param>
    ''' <param name="watermarkText">水印文字</param>
    ''' <param name="WatermarkPosition">图片水印位置</param>
    Public Function CreateWatertextBitmap(tn As Image, WaterMarkText As String, WatermarkPosition As String) As Image
        Try
            Dim g As Graphics = Graphics.FromImage(tn)

            '高质量图片
            g.SmoothingMode = SmoothingMode.HighQuality
            g.InterpolationMode = InterpolationMode.High
            g.PixelOffsetMode = PixelOffsetMode.HighQuality

            Dim drawFont As New Font(Watermarkfontname, Watermarkfontsize, FontStyle.Regular, GraphicsUnit.Pixel)
            Dim crSize As SizeF
            crSize = g.MeasureString(WaterMarkText, drawFont)

            Dim X As Single = 0, Y As Single = 0, X1 As Single = 0, Y1 As Single = 0
            '水印位置
            Select Case WatermarkPosition
                Case "Right"
                    X = tn.Width - crSize.Width
                    Y = CSng(tn.Height / 2 - crSize.Height / 2)
                    Exit Select
                Case "RightTop"
                    X = tn.Width - crSize.Width
                    Y = 0
                    Exit Select
                Case "Top"
                    X = CSng(tn.Width / 2 - crSize.Width / 2)
                    Y = 0
                    Exit Select
                Case "LeftTop"
                    X = 0
                    Y = 0
                    Exit Select
                Case "Left"
                    X = 0
                    Y = CSng(tn.Height / 2 - crSize.Height / 2)
                    Exit Select
                Case "LeftBottom"
                    X = 0
                    Y = tn.Height - crSize.Height
                    Exit Select
                Case "Bottom"
                    X = CSng(tn.Width / 2 - crSize.Width / 2)
                    Y = tn.Height - crSize.Height
                    Exit Select
                Case "RightBottom"
                    X = tn.Width - crSize.Width
                    Y = tn.Height - crSize.Height
                    Exit Select
                Case "Center"
                    X = CSng(tn.Width / 2 - crSize.Width / 2)
                    Y = CSng(tn.Height / 2 - crSize.Height / 2)
                    Exit Select
            End Select
            X = If(X = 0, 2, X)
            Y = If(Y = 0, 2, Y)

            '白笔刷，画文字用  黑笔刷，画背景用  
            'Dim whiteBrush As New SolidBrush(Color.White), blackBrush As New SolidBrush(Color.Black)

            'Dim rectX As Decimal = 0, rectY As Decimal = 0, textWidth As Decimal = WaterMarkText.Length * Watermarkfontsize

            'Dim rectWidth As Decimal = tn.Width, rectHeight As Decimal = Watermarkfontsize + 8

            'rectY = tn.Height - rectHeight

            'Dim textArea As RectangleF = New RectangleF(rectWidth - textWidth, rectY + 4, rectWidth, rectHeight)

            'g.FillRectangle(blackBrush, rectX, rectY, rectWidth, rectHeight)
            'g.DrawString(WaterMarkText, drawFont, whiteBrush, textArea)

            g.DrawString(WaterMarkText, drawFont, New SolidBrush(Color.DimGray), X + 1, Y + 1)
            g.DrawString(WaterMarkText, drawFont, New SolidBrush(Color.White), X, Y)

            drawFont.Dispose()
            drawFont = Nothing
            Return tn
        Catch ex As Exception
            Util.toLog(String.Concat(Now(), " - CreateWatertextBitmap:", ex.Message))
            Return tn
        End Try
    End Function


    ''' <summary>
    ''' 翻转图像
    ''' </summary>
    ''' <param name="src"></param>
    ''' <param name="angle"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Function RotateBitmap(src As String, angle As Single) As String
        Try
            Dim OrgFileName As String
            '是否存在基础目录
            If Not String.IsNullOrEmpty(UploadBasePath) AndAlso IO.Directory.Exists(UploadBasePath) Then
                OrgFileName = String.Concat(UploadBasePath, src)
            Else
                OrgFileName = System.Web.HttpContext.Current.Server.MapPath(src)
            End If

            Dim oldImage As Image = Bitmap.FromFile(OrgFileName)

            Dim newBmp As Bitmap = BitmapCutter.RotateImage(oldImage, angle)
            oldImage.Dispose()
            Dim nw As Integer = newBmp.Width
            Dim nh As Integer = newBmp.Height
            newBmp.Save(OrgFileName)
            newBmp.Dispose()
            Return "{""msg"":""success"",""size"":{""width"":""" + nw.ToString() + """,""height"":""" + nh.ToString() + """}}"
        Catch ex As Exception
            Return "{""msg"":""" + ex.Message + """}"
        End Try
    End Function

    ''' <summary>
    ''' 裁剪图片
    ''' </summary>
    ''' <param name="src"></param>
    ''' <param name="uploadCtrl"></param>
    ''' <param name="zoom"></param>
    ''' <param name="x"></param>
    ''' <param name="y"></param>
    ''' <param name="cutwidth"></param>
    ''' <param name="cutheight"></param>
    ''' <returns></returns>
    ''' <remarks></remarks>
    ''' 
    Public Function CuteBitmap(src As String, uploadCtrl As Config.UploadControl, zoom As Double, x As Integer, y As Integer, cutwidth As Integer, cutheight As Integer) As String
        Try
            Dim OrgFileName As String
            Dim FilePath As String
            Dim RandomPath As String = Util.GetRandomDirectory()
            Dim RandomFile As String = Util.GetRandomFileName(src)
            Dim VFileUrl As String = String.Concat(RandomPath, RandomFile)

            Dim rUploadPath As String

            '是否传送上传目录
            If String.IsNullOrEmpty(uploadCtrl.UploadPath) Then
                rUploadPath = UploadPath
            Else
                rUploadPath = uploadCtrl.UploadPath
            End If


            '是否存在基础目录
            If Not String.IsNullOrEmpty(UploadBasePath) AndAlso IO.Directory.Exists(UploadBasePath) Then
                FilePath = String.Concat(UploadBasePath, rUploadPath, VFileUrl)
                OrgFileName = String.Concat(UploadBasePath, src)
            Else
                FilePath = System.Web.HttpContext.Current.Server.MapPath(String.Concat(rUploadPath, VFileUrl))
                OrgFileName = System.Web.HttpContext.Current.Server.MapPath(src)
            End If

            If Not IO.File.Exists(OrgFileName) Then
                Return "{""msg"":""文件不存在""}"
            End If

            'Dim fi As New IO.FileInfo(src)
            'Dim ext As String = fi.Extension

            'Image.GetThumbnailImageAbort abort = null;

            Dim oldBitmap As New Bitmap(OrgFileName)
            Dim cut As New Cutter(zoom, x, y, cutwidth, cutheight, oldBitmap.Width, oldBitmap.Height)

            Dim oldformat As ImageFormat = oldBitmap.RawFormat
            Dim bmp As Bitmap

            Try
                bmp = BitmapCutter.GenerateBitmap(oldBitmap, cut)
                oldBitmap.Dispose()

                bmp.Save(FilePath, oldformat)
                bmp.Dispose()

            Catch ex As Exception
                oldBitmap.Dispose()
                oldBitmap = Nothing
                Return "{""msg"":""" + String.Concat("OrgFileName:", OrgFileName, ",cut:x=", cut.X, ",y=", cut.Y, ",zoom=", cut.Zoom, ",CutterWidth=", cut.CutterWidth, ",CutterHeight=", cut.CutterHeight, ",SaveWidth=", cut.SaveWidth, ",SaveHeight=", cut.SaveHeight, ",Width=", cut.Width, ",Height=", cut.Height) + ex.Message + """}"
            End Try

            Return "{""msg"":""success"",""src"":""" + String.Concat(rUploadPath, VFileUrl) + """}"

        Catch ex As Exception

            Return "{""msg"":""" + ex.Message + """}"
        End Try
    End Function
#End Region

End Class


